package cn.com.hhrcw.enterprise.web;

import cn.com.hhrcw.enterprise.params.EnNewsParams;
import cn.com.hhrcw.enterprise.params.SysAnnouncementParams;
import cn.com.hhrcw.enterprise.vo.EnNewsVO;
import cn.com.hhrcw.enterprise.vo.SysAnnouncementVO;
import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.mapstruct.*;
import cn.com.hhrcw.service.*;
import cn.com.hhrcw.utils.SubjectUtils;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.aspect.annotation.PermissionData;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * 消息
 *
 * @program: recruit-boot-parent
 * @description: 消息
 * @author: JD
 * @create: 2020-11-11 10:15
 **/
@RestController
@RequestMapping("/en/message")
@Slf4j
public class EnMessageController {

    @Autowired
    EnEnNewsConvert newsConvert;

    @Autowired
    IEnNewsService newsService;

    @Autowired
    SysAnnouncementService sysAnnouncementService;

    @Autowired
    EnSysAnnouncementConvert sysAnnouncementConvert;

    @Autowired
    IOpInterviewHistoryService historyService;

    @Autowired
    IOpEntryHistoryService entryHistoryService;

    @Autowired
    IOpJobService jobService;

    @Autowired
    EnOpJobConvert jobConvert;

    @Autowired
    IPiInfoService piInfoService;

    @Autowired
    EnPiInfoConvert piInfoConvert;

    @Autowired
    IOpDeliveryHistoryService deliveryHistoryService;

    @Autowired
    IOpInterviewHistoryService interviewHistoryService;

    @Autowired
    EnOpInterviewHistoryConvert interviewHistoryConvert;

    @Autowired
    IEnContactsService contactsService;

    @Autowired
    EnEnContactsConvert contactsConvert;

    @Autowired
    EnOpDeliveryHistoryConvert deliveryHistoryConvert;

    /**
     * 获取未读消息数量
     *
     * @return
     */
    @GetMapping("/getNotReadCount")
    @AutoLog(logType = 2, ty = "visit", value = "未读消息数量查询")
    public Result<Integer> getCount() {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        int count = newsService.lambdaQuery().eq(EnNews::getReadFlag, false).in(EnNews::getReceiveId, sysUser.getId()).eq(EnNews::getDelFlag, false).eq(EnNews::getReceiveType, 1).count();
        return Result.ok(count);
       /* List<String> objId = new ArrayList<>();
        List<OpJob> jobs = jobService.lambdaQuery().eq(OpJob::getDelFlag, false).eq(OpJob::getCreateBy, sysUser.getId()).list();
        if (!CollectionUtils.isEmpty(jobs)) {

            List<String> jobIds = new ArrayList<>();
            jobs.forEach(e -> {
                jobIds.add(e.getId());
            });
            //投递

            List<OpDeliveryHistory> deliveryHistories = deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds).list();
            if (!CollectionUtils.isEmpty(deliveryHistories)) {
                deliveryHistories.forEach(d -> {
                    objId.add(d.getId());
                });
            }

            //面试
            List<OpInterviewHistory> histories = interviewHistoryService.lambdaQuery().eq(OpInterviewHistory::getDelFlag, false).in(OpInterviewHistory::getJobId, jobIds).list();
            if (!CollectionUtils.isEmpty(histories)) {
                histories.forEach(h -> {
                    objId.add(h.getId());
                });
            }

            //入职

            List<OpEntryHistory> entryHistories = entryHistoryService.lambdaQuery().eq(OpEntryHistory::getDelFlag, false).in(OpEntryHistory::getJobId, jobIds).list();
            if (!CollectionUtils.isEmpty(entryHistories)) {
                entryHistories.forEach(en -> {
                    objId.add(en.getId());
                });
            }
        }
        int count = 0;
        if (!CollectionUtils.isEmpty(objId)) {
            count = newsService.lambdaQuery().eq(EnNews::getReadFlag, false).in(EnNews::getObjId, objId)
                    .eq(EnNews::getDelFlag, false).count();
        }
        return Result.ok(count);*/
    }

    /**
     * 根据id查询
     *
     * @param id 数据id
     * @return
     */
    @GetMapping(value = "/queryById")
    @ApiOperation(value = "根据id查询", notes = "根据id查询")
    @AutoLog(logType = 2, ty = "visit", value = "消息内容查询")
    @PermissionData
    public Result<EnNewsVO> queryById(String id) {
        EnNews enNews = newsService.lambdaQuery().eq(EnNews::getId, id).eq(EnNews::getDelFlag, false).one();
        if (enNews == null) {
            throw new JeecgBootException("数据不存在");
        }
        return Result.ok(newsConvert.toVO(enNews));
    }

    /**
     * 发送消息
     *
     * @param params 请求参数
     * @return
     */
    @PostMapping(value = "/add")
    @AutoLog(logType = 2, ty = "insert", value = "发送消息")
    @ApiOperation(value = "添加", notes = "添加")
    @RequiresPermissions("enNews:add")
    public Result<?> add(@RequestBody @Valid EnNewsParams params) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        EnNews enNews = newsConvert.toEntity(params);
        enNews.setCreateBy(sysUser.getId());
        enNews.setCreateTime(DateUtil.date());
        enNews.setDelFlag(false);

        //enNews.setNo(super.sort("en_news", Constant.NO_SEED));//FIXME: 编号,可根据情况隐藏
        boolean saved = newsService.save(enNews);
        return saved ? Result.ok() : Result.error("添加失败");
    }

    /**
     * 编辑
     *
     * @param params 请求参数
     * @return
     */
    @PostMapping(value = "/edit")
    @AutoLog(logType = 2, ty = "update", value = "消息编辑")
    @ApiOperation(value = "编辑", notes = "编辑")
    @RequiresPermissions("enNews:edit")
    public Result<?> edit(@RequestBody @Valid EnNewsParams params) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        EnNews enNews = newsConvert.toEntity(params);
        enNews.setUpdateBy(sysUser.getId());
        enNews.setUpdateTime(DateUtil.date());
        boolean updated = newsService.updateById(enNews);
        return updated ? Result.ok() : Result.error("编辑失败");
    }

    /**
     * 批量删除
     *
     * @param id 数据id
     * @return
     */
    @GetMapping(value = "/delete")
    @AutoLog(logType = 2, ty = "delete", value = "消息删除")
    @ApiOperation(value = "批量删除", notes = "批量删除")
    @RequiresPermissions("enNews:delete")
    public Result delete(String[] id) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        LambdaUpdateWrapper<EnNews> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.in(EnNews::getId, id).set(EnNews::getDelFlag, true).set(EnNews::getUpdateBy, sysUser.getUsername()).set(EnNews::getUpdateTime, DateUtil.date());

        boolean deleted = newsService.update(updateWrapper);
        return deleted ? Result.ok() : Result.error("删除失败");
    }

    /**
     * 消息列表,包含详情
     *
     * @param params
     * @return
     */
    @GetMapping("/message/list")
    @AutoLog(logType = 2, ty = "visit", value = "消息列表")
    public Result<Page<EnNewsVO>> messageList(EnNewsParams params) {
        LambdaQueryWrapper<EnNews> queryWrapper = new LambdaQueryWrapper<>();
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        queryWrapper.eq(EnNews::getDelFlag, false)
                .eq(EnNews::getReceiveType, 1)
                .in(EnNews::getReceiveId, sysUser.getId())
                .orderByDesc(EnNews::getCreateTime);
        IPage<EnNews> page = newsService.page(params.page(), queryWrapper);
        Function<EnNews, EnNewsVO> function = news -> {
            EnNewsVO vo = newsConvert.toVO(news);
            //0投递1面试2录用3拒绝面试4接受面试5阅读6接受入职7拒绝入职8简历不合适通知9面试通过10面试未通过
            boolean newsTypeFlag = "2".equals(vo.getNewsType()) || "6".equals(vo.getNewsType())
                    || "7".equals(vo.getNewsType());
            boolean newsTypeElseFlag = "1".equals(vo.getNewsType()) || "3".equals(vo.getNewsType())
                    || "4".equals(vo.getNewsType()) || "9".equals(vo.getNewsType()) || "10".equals(vo.getNewsType());
            if (newsTypeFlag) {
                OpEntryHistory opEntryHistory = entryHistoryService.getById(vo.getObjId());

                if (opEntryHistory != null) {
                    vo.setEntryHistory(opEntryHistory);
                    EnContacts enContacts = contactsService.getById(opEntryHistory.getContactId());
                    vo.setEnContacts(enContacts);
                    OpJob opJob = jobService.getById(opEntryHistory.getJobId());
                    vo.setJob(opJob);

                    PiInfo piInfo = piInfoService.lambdaQuery().eq(PiInfo::getDelFlag, false).eq(PiInfo::getUserId, opEntryHistory.getUserId()).one();
                    vo.setPiInfo(piInfo);
                }
            } else if (newsTypeElseFlag) {
                OpInterviewHistory interviewHistory = interviewHistoryService.getById(vo.getObjId());
                if (interviewHistory != null) {
                    String conId = interviewHistory.getContactId();
                    EnContacts enContacts = contactsService.getById(conId);
                    vo.setInterviewHistory(interviewHistory);
                    vo.setEnContacts(enContacts);

                    OpJob opJob = jobService.getById(interviewHistory.getJobId());
                    vo.setJob(opJob);

                    PiInfo piInfo = piInfoService.lambdaQuery().eq(PiInfo::getDelFlag, false).eq(PiInfo::getUserId, interviewHistory.getUserId()).one();
                    vo.setPiInfo(piInfo);
                }

            }
            return vo;
        };
        return Result.ok((Page) page.convert(function));
    }

    /**
     * 招聘消息列表
     *
     * @param params
     * @return
     */
    @GetMapping("/list")
    @AutoLog(logType = 2, ty = "visit", value = "招聘消息列表查询")
    public Result<Page<EnNewsVO>> list(EnNewsParams params) {
        List<String> ids = new ArrayList<>();
        if (params.getType() == 0 || params.getType() == 1) {
            String objId = params.getObjId();
            ids.add(objId);
            OpInterviewHistory opInterviewHistory = historyService.getById(params.getObjId());
            if (opInterviewHistory != null) {
                ids.add(opInterviewHistory.getId());
            }

            List<OpInterviewHistory> list = historyService.lambdaQuery().eq(OpInterviewHistory::getUserId, opInterviewHistory.getUserId()).eq(OpInterviewHistory::getJobId, opInterviewHistory.getJobId()).eq(OpInterviewHistory::getDelFlag, false).list();
            if (!CollectionUtils.isEmpty(list)) {
                list.forEach(e -> {
                    ids.add(e.getId());
                });
            }
            OpEntryHistory entryHistory = entryHistoryService.lambdaQuery().eq(OpEntryHistory::getUserId, params.getUserId()).eq(OpEntryHistory::getJobId, opInterviewHistory.getJobId()).eq(OpEntryHistory::getDelFlag, false).one();
            if (entryHistory != null) {
                ids.add(entryHistory.getId());
            }
        } else {
            List<OpInterviewHistory> opInterviewHistory = historyService.lambdaQuery().eq(OpInterviewHistory::getUserId, params.getUserId()).eq(OpInterviewHistory::getJobId, params.getObjId()).eq(OpInterviewHistory::getDelFlag, false).list();
            if (!CollectionUtils.isEmpty(opInterviewHistory)) {
                opInterviewHistory.forEach(e -> {
                    ids.add(e.getId());
                });
            }
            ids.add(params.getObjId());
            List<OpEntryHistory> entryHistory = entryHistoryService.lambdaQuery().eq(OpEntryHistory::getUserId, params.getUserId()).eq(OpEntryHistory::getJobId, params.getObjId()).eq(OpEntryHistory::getDelFlag, false).list();
            if (!CollectionUtils.isEmpty(entryHistory)) {
                entryHistory.forEach(e -> {
                    ids.add(e.getId());
                });
            }

            List<OpDeliveryHistory> opDeliveryHistory = deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getUserId, params.getUserId()).eq(OpDeliveryHistory::getJobId, params.getObjId()).eq(OpDeliveryHistory::getDelFlag, false).list();
            if (!CollectionUtils.isEmpty(opDeliveryHistory)) {
                opDeliveryHistory.forEach(e -> {
                    ids.add(e.getId());
                });
            }
        }

        LambdaQueryWrapper<EnNews> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EnNews::getDelFlag, false).in(EnNews::getObjId, ids).orderByDesc(EnNews::getCreateTime);
        IPage<EnNews> page = newsService.page(params.page(), queryWrapper);
        Function<EnNews, EnNewsVO> function = news -> newsConvert.toVO(news);
        return Result.ok((Page) page.convert(function));
    }


    /**
     * 消息-系统通知-未读数量
     *
     * @param params 请求参数
     * @return
     */
    @GetMapping(value = "/sys/list/notRead")
    @AutoLog(logType = 2, ty = "visit", value = "系统通知-未读数量查询")
    @ApiOperation(value = "分页列表查询", notes = "分页列表查询")
    @PermissionData
    public Result<Page<SysAnnouncementVO>> notRead(SysAnnouncementParams params) {
        LoginUser sysUser = (LoginUser) SubjectUtils.getSubject();
        LambdaQueryWrapper<SysAnnouncement> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysAnnouncement::getDelFlag, false).eq(SysAnnouncement::getMsgType, "ALL").or(query -> query.eq(SysAnnouncement::getMsgType, "USER").eq(SysAnnouncement::getUserIds, sysUser.getId()));
        IPage<SysAnnouncement> page = sysAnnouncementService.page(params.page(), queryWrapper);
        //分页结果转换器
        Function<SysAnnouncement, SysAnnouncementVO> fun = sysAnnouncement -> sysAnnouncementConvert.toVO(sysAnnouncement);
        return Result.ok((Page) page.convert(fun));
    }

    /**
     * 消息-系统通知
     *
     * @param params 请求参数
     * @return
     */
    @GetMapping(value = "/sys/list")
    @AutoLog(logType = 2, ty = "visit", value = "系统通知列表查询")
    @ApiOperation(value = "分页列表查询", notes = "分页列表查询")
    @PermissionData
    public Result<Page<SysAnnouncementVO>> list(SysAnnouncementParams params) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        LambdaQueryWrapper<SysAnnouncement> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysAnnouncement::getDelFlag, false).eq(SysAnnouncement::getMsgType, "ALL").or(query -> query.eq(SysAnnouncement::getMsgType, "USER").eq(SysAnnouncement::getUserIds, sysUser.getId()));
        IPage<SysAnnouncement> page = sysAnnouncementService.page(params.page(), queryWrapper);
        //分页结果转换器
        Function<SysAnnouncement, SysAnnouncementVO> fun = sysAnnouncement -> sysAnnouncementConvert.toVO(sysAnnouncement);
        return Result.ok((Page) page.convert(fun));
    }
}
